#!/usr/bin/python
#
# Copyright (C) 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


__author__ = 'ales.kotnik@gmail.com (Ales Kotnik)'


try:
  from xml.etree import ElementTree
except ImportError:
  from elementtree import ElementTree
import gdata.spreadsheet.service
import gdata.service
import atom.service
import gdata.spreadsheet
import atom
import sys
import string
import logging
from invoice import Invoice, InvoiceLineItem
from party import Party




class InvoiceCollector():
  def __init__(self, email, password, spreadsheet):
    self.gd_client = gdata.spreadsheet.service.SpreadsheetsService()
    self.gd_client.email = email
    self.gd_client.password = password
    self.gd_client.source = 'Fakture GData'
    self.gd_client.ProgrammaticLogin()
    self.spreadsheet = spreadsheet        
    self.curr_key = ''
    self.curr_wksht_id = ''
    self.list_feed = None
    self.invoices={}
    self.parties={}
    self.me = None # invoicing party

  def _StringToDictionary(self, row_data):
    dict = {}
    for param in row_data.split(','):
      temp = param.split(':')
      dict[temp[0].strip()] = temp[1].strip()
    return dict

  def selectSpreadsheet(self, name):
    bSelected = False
    feed = self.gd_client.GetSpreadsheetsFeed()
    for i, entry in enumerate(feed.entry):
      if entry.title.text == self.spreadsheet:
        self.curr_key = feed.entry[i].id.text.rsplit('/', 1)[1]
        bSelected = True
        break
    if bSelected == False:
      raise "Can't get spreadsheet %s" %name        
    logging.debug("Document id: %s" % self.curr_key)        

  
  def selectWorksheet(self, name):
    bSelected = False  
    feed = self.gd_client.GetWorksheetsFeed(self.curr_key)
    for i, entry in enumerate(feed.entry):
      if entry.title.text == name:
        self.curr_wksht_id = feed.entry[i].id.text.rsplit('/', 1)[1]
        bSelected = True
        break
    if bSelected == False:
      raise "Can't get worksheet %s" %name        
    logging.debug("Worksheet id: %s" %self.curr_wksht_id)
    
    
  def fetchParties(self):
    """Caches all parties"""
    self.selectWorksheet('parties')
    feed = self.gd_client.GetListFeed(self.curr_key, self.curr_wksht_id)
    logging.debug("Fetching parties ...")
    for i, entry in enumerate(feed.entry):
      dct = self._StringToDictionary(entry.content.text)
      party = Party()
      for field in "id desc street zip city state country vat me tax_number".split():
        if dct.has_key(field):
          setattr(party,field, dct[field])
        else:
          setattr(party,field,'')
      logging.debug("Fetcing party %s" %party.id)
      self.parties[party.id] = party

    if party.me != '':
      self.me = party
    
  def fetchInvoices(self):
    self.selectSpreadsheet(self.spreadsheet)
    
    # partnerji
    self.fetchParties()
    
    if self.me is None:
      raise "No invoicing party"
    logging.debug("Invoicing party: %s" %self.me.desc)
    
    self.selectWorksheet('sent')
    
    # listaj fakture
    feed = self.gd_client.GetListFeed(self.curr_key, self.curr_wksht_id)
    
    bItems = False # procssing mode header/items
    logging.debug("Fetcing invoices")
    for i, entry in enumerate(feed.entry):
      dct = self._StringToDictionary(entry.content.text)
         
      if dct.has_key('id'):
        if dct['id'] == "#":
           continue
        if dct.has_key('print'):
          # procesiraj glavo
          logging.debug("Faktura %s:" %dct['id'])
          bItems = True
          invoice = Invoice()
          invoice.id = dct['id']
          invoice.document_date = dct['c1']
          invoice.party_id = dct['c2']
          invoice.date_due = dct['c3']          
          invoice.date_from = dct['c4']
          if dct.has_key('c5'):
            invoice.date_to = dct['c5']
          else:
            invoice.date_to = dct['c4']
          invoice.me = self.me
          if self.parties.has_key(invoice.party_id) == False:
            raise "Invoice %s has unexistent party %s" %(invoice.id, invoice.party_id)
          else:
            invoice.party = self.parties[invoice.party_id]
            
          invoice.lineitems=[]
          self.invoices[dct['id']] = invoice
          logging.debug("Fetching invoice %s for %s" %(invoice.id, invoice.party.desc))
          continue
        else:
          bItems = False
      
      if bItems == True and not dct.has_key('id'):
        try:
          lineitem = InvoiceLineItem()
          lineitem.id = dct['c1'] # line id
          if dct.has_key('c2'):
            lineitem.asset_id = dct['c2'] # asset id
          else:
            lineitem.asset_id = ''
          lineitem.asset_desc = dct['c3'] # description
          lineitem.item_price = dct['c4'] # price per item
          lineitem.qty = dct['c5'] # quantity
          lineitem.uom = dct['c6'] # unit of measure
          
          invoice.lineitems.append(lineitem)
          
          logging.debug("%s %s" %(lineitem.id, lineitem.asset_desc))
        except:
          print dct
          raise
          pass
        


